import tkinter as tk
import os
import json
from tkinter import messagebox

from scrollable_widgets import create_scrollable_canvas
from utils import create_centered_window, bind_mousewheel


class WorkflowSelector:
    def __init__(self, main_window, workflows_dir, auto_mode):
        self.main_window = main_window
        self.workflows_dir = workflows_dir
        self.auto_mode = auto_mode

        # 选中的工作流变量
        self.workflow_var = None

        self.window = create_centered_window(
            title="选择工作流",
            width=600,
            height=500,
            window_type='top',
            parent=main_window
        )

        # 设置合适的窗口尺寸
        self.window.minsize(500, 400)

        # 功能：将指定的widget设置为"抓取"状态，使其成为模态窗口
        # 作用：抓取会将所有事件（鼠标和键盘输入）定向到该widget及其子widget
        # 效果：用户必须先处理这个窗口才能与应用程序中的其他窗口交互
        self.window.grab_set()

        # 关闭窗口时返回主菜单而不是退出程序
        self.window.protocol("WM_DELETE_WINDOW", self.back_to_main)

        self.create_widgets()

    def list_available_workflows(self):
        """列出所有可用的工作流程文件"""
        workflows = []
        # 创建工作流目录（如果不存在）
        if not os.path.exists(self.workflows_dir):
            os.makedirs(self.workflows_dir)

        for file in os.listdir(self.workflows_dir):
            if file.endswith(".json"):
                workflows.append(file)

        return workflows

    def load_workflow_file(self, file_path):
        """加载工作流文件并返回解析后的数据，如果出错显示错误信息并返回None"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)

            # 检查必要字段
            if 'steps' not in data:
                raise ValueError("文件格式错误：缺少steps字段")

            if 'delay_settings' not in data:
                raise ValueError("文件格式错误：缺少delay_settings字段")

            if 'custom_delay_settings' not in data:
                raise ValueError("文件格式错误：缺少custom_delay_settings字段")

            # 返回工作流数据
            return data
        except json.JSONDecodeError as e:
            messagebox.showerror("工作流文件错误", "文件格式不正确，请检查是否为有效的JSON格式")
            return None
        except Exception as e:
            messagebox.showerror("工作流文件错误", str(e))
            return None

    def create_widgets(self):
        # 创建主框架
        main_frame = tk.Frame(self.window, padx=20, pady=20)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = tk.Label(
            main_frame,
            text="选择要执行的工作流",
            font=("微软雅黑", 14, "bold"),
            fg='#333333'
        )
        title_label.pack()

        # 工作流选择框架
        workflow_frame = tk.LabelFrame(
            main_frame,
            text="可用工作流",
            font=("微软雅黑", 10, "bold"),
            height=150  # 设置固定高度
        )
        workflow_frame.pack_propagate(False)  # 固定LabelFrame大小,即使内部组件很大，LabelFrame也不会变大
        workflow_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=20)

        # 创建滚动区域来容纳所有内容
        canvas = create_scrollable_canvas(workflow_frame)
        canvas.pack(fill=tk.BOTH, expand=True)



        self.workflow_var = tk.StringVar()
        # 获取可用的工作流
        workflows = self.list_available_workflows()

        # 添加已录制的工作流选项
        y_position = 10
        for workflow in workflows:
            radio = tk.Radiobutton(
                canvas,
                text=workflow,
                variable=self.workflow_var,
                value=workflow,
                anchor="w",
                font=("微软雅黑", 10),
                pady=5,
                # 是 widget 自身的"请求宽度"，而不是实际分配的宽度或可用宽度
                width=canvas.winfo_reqwidth()
            )
            canvas.create_window(10, y_position, window=radio, anchor="nw")
            y_position += 30

        if not workflows:
            # 添加提示标签，当没有工作流时显示
            no_workflow_label = tk.Label(
                canvas,
                text="暂无可用工作流",
                fg="gray",
                font=("微软雅黑", 10)
            )
            canvas.create_window(10, 10, window=no_workflow_label, anchor="nw")
        else:
            # 默认选择第一个工作流
            self.workflow_var.set(workflows[0])

        # 更新滚动区域以包含所有内容
        canvas.configure(scrollregion=canvas.bbox("all"))

        # 对选择工作流的窗口绑定鼠标滚轮事件
        bind_mousewheel(canvas, event_widget=self.window)

        # 控制按钮框架
        button_frame = tk.Frame(main_frame)
        button_frame.pack(pady=(0, 10))

        # 启动执行器按钮
        start_button = tk.Button(
            button_frame,
            text="启动执行器",
            command=self.start_execution,
            font=("微软雅黑", 11),
            width=12,
            relief=tk.RAISED,
            cursor='hand2'
        )
        # 修改按钮布局，居中显示
        start_button.pack(side=tk.LEFT, padx=(0, 10))

        # 取消按钮
        cancel_button = tk.Button(
            button_frame,
            text="取消",
            command=self.back_to_main,
            font=("微软雅黑", 11),
            width=12,
            relief=tk.RAISED,
            cursor='hand2'
        )
        cancel_button.pack(side=tk.LEFT)

    def start_execution(self):
        """启动执行器"""
        selected_workflow = self.workflow_var.get()
        if selected_workflow:
            file_path = os.path.join(self.workflows_dir, selected_workflow)

            # 加载工作流文件
            workflow_data = self.load_workflow_file(file_path)
            if workflow_data is None:
                return  # 错误信息已经在load_workflow_file中显示了

            # 关闭选择窗口
            self.window.destroy()
            # 创建并运行工作流执行器，传递解析后的数据
            if self.auto_mode:
                # 自动执行
                from auto_executor import AutoExecutor
                AutoExecutor(workflow_data, file_path, self.main_window)
            else:
                # 手动执行
                from manual_executor import ManualExecutor
                ManualExecutor(workflow_data["steps"], self.main_window)

    def back_to_main(self):
        """返回主窗口"""
        self.window.destroy()
        self.main_window.deiconify()
